/* Copyright 2009 Requirements Management System 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mags.remas.view;

import java.util.List; 
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.validator.GenericValidator;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IEditorInput;
import org.mags.remas.control.EntityRelationshipController;
import org.mags.remas.control.SubEntitiesViewController;
import org.mags.remas.logic.EntityLogic;
import org.mags.remas.model.entity.Entity;
import org.mags.remas.model.entity.EntityRelationship;
import org.mags.remas.model.entity.EntityStructure;
import org.mags.remas.view.commons.IActionMenuMaker;
import org.mags.remas.view.commons.TreeActionMaker;

/**
 * 
 * @author Mario Gaitan
 *
 */
public class SubentitiesEditor extends AbstractSubentitiesEditor 
	implements IActionMenuMaker {
	public static final String ID = "org.mags.remas.view.subentitiesEditor";
	private EntityRelationshipController viewController;
	private TreeActionMaker treeActionMaker;
	@Override
	public void init(IEditorInput input) {
		viewController = new SubEntitiesViewController();
	}	
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		getTreeViewer().setContentProvider(viewController);
		getTreeViewer().setLabelProvider(viewController);		
		getTreeViewer().setRoot(entityRelationship);
		treeActionMaker = new TreeActionMaker(getTreeViewer(), viewController, super.getSite());
		treeActionMaker.makeActions();
		treeActionMaker.makeMenu();
		treeActionMaker.setActionMenuMaker(this);
	}
	public void makeMenuForDrop(IMenuManager manager) {
		List<EntityStructure> allowedTypes = EntityLogic.getInstance().getEntityTypeChildren(getTreeViewer().getTargetToDrop().getEntity().getEntityType());
		boolean allowedType=false;
		boolean allAllowedTypes = true;
		boolean ignoreRest = false;
		for(EntityRelationship j: getTreeViewer().getElementsDroped()) {
			allowedType=false;
			for(EntityStructure i: allowedTypes) {
				if(i.getEntityType().getEntityTypeId()==j.getEntity().getEntityType().getEntityTypeId()) {
					allowedType = true;
					break;
				}
			}
			if(allowedType) {
				if(j.getEntityParent().getEntityId()==getTreeViewer().getTargetToDrop().getEntity().getEntityId()
					&& j.getHierarchicalPath().startsWith(getTreeViewer().getTargetToDrop().getHierarchicalPath())) {
					ignoreRest = true;
					break;
				}
				else if(getTreeViewer().getTargetToDrop().getHierarchicalPath().startsWith(j.getHierarchicalPath())) {
					ignoreRest = true;
					break;
				}
			} else {
				allAllowedTypes = false;
				break;
			}
		}
		boolean allBrothers = true;
		boolean moveAbove = true;
		boolean moveBelow = true;
		List<EntityRelationship> entityRelationshipList = getTreeViewer().getElementsDroped();
		EntityRelationship targetToDrop = getTreeViewer().getTargetToDrop();
		if(!ignoreRest) {
			for(EntityRelationship j: entityRelationshipList) {
				if(getTreeViewer().getTargetToDrop().getEntityParent()==null
					||(j.getParent()!=null&&!targetToDrop.getParent().getHierarchicalPath().equals(j.getParent().getHierarchicalPath()))
					||j.getEntityParent().getEntityId()!=getTreeViewer().getTargetToDrop().getEntityParent().getEntityId()
					||j.getEntityRelationshipId()==getTreeViewer().getTargetToDrop().getEntityRelationshipId()) {
					allBrothers = false;
					if(!allAllowedTypes) {
						ignoreRest = true;
						break;
					}
					else
						break;
				} else {
					if(moveAbove&&getTreeViewer().getTargetToDrop().getPosition()+1==j.getPosition()) {
						if(!moveBelow&&!allAllowedTypes) {
							ignoreRest = true;
							break;
						}
						else
							moveAbove=false;
					}		
					if(moveBelow&&getTreeViewer().getTargetToDrop().getPosition()-1==j.getPosition()) {
						if(!moveAbove&&!allAllowedTypes) {
							ignoreRest = true;
							break;
						}
						else
							moveBelow = false;
					}
				}
			}	
		}
		if(!ignoreRest) {
			if(allBrothers
				&& getTreeViewer().getElementsDroped().size()==1 //TEMPORAL
			) {
				if(moveAbove)
					manager.add(treeActionMaker.getMoveAboveAction());
				if(moveBelow)
					manager.add(treeActionMaker.getMoveBelowAction());
			}
			if(allAllowedTypes) {
				manager.add(new Separator());
				manager.add(treeActionMaker.getMoveAction());
				manager.add(treeActionMaker.getCopyAction());
			}
		}
		boolean reference = true;
		for(EntityRelationship j: entityRelationshipList) {
			if(j.getEntity().getEntityId()==targetToDrop.getEntity().getEntityId()) {
				reference = false;
				break;
			}
		}
		if(reference) {
			manager.add(new Separator());
			manager.add(treeActionMaker.getReferenceFromAction());
			manager.add(treeActionMaker.getReferenceToAction());
		}		
	}
	public void makeMenuForRightClick(IMenuManager manager) {
		final EntityRelationship entityRelationship = getTreeViewer().getSelectedElement();
		Entity entity = entityRelationship.getEntity();
		List<Action> actions = treeActionMaker.makeDinamicallyActions();
		if(actions.size()>0) {
			for(Action i: actions)
				manager.add(i);
			manager.add(new Separator());
		}
		if(!GenericValidator.isBlankOrNull(entity.getEntityType().getPreviewClass()))
			manager.add(treeActionMaker.getPreviewAction());
		if(!GenericValidator.isBlankOrNull(entity.getEntityType().getProcessClass()))
			manager.add(treeActionMaker.getProcessAction());
		if(!GenericValidator.isBlankOrNull(entity.getEntityType().getEditfileClass()))
			manager.add(treeActionMaker.getEditFileAction());
		manager.add(new Separator());
		manager.add(treeActionMaker.getEditAction());
		manager.add(treeActionMaker.getDeleteAction());
		if(entityRelationship.getLink()!=null)
			manager.add(treeActionMaker.getSelectLinkInViewAction());
		manager.add(treeActionMaker.getRefreshAction());
		manager.add(new Separator());
		manager.add(treeActionMaker.getReferencesFromAction());
		manager.add(treeActionMaker.getReferencesToAction());
		manager.add(new Separator());
		manager.add(treeActionMaker.getCommentsAction());
		manager.add(treeActionMaker.getAddCommentAction());
		manager.add(treeActionMaker.getPropertiesAction());		
	}
	public boolean dragAndDrop(EntityRelationship target, List<EntityRelationship> elementsDroped) {
		treeActionMaker.getMenuDrop().setVisible(true);
		return true;
	}
	@Override
	public void update(EntityRelationship entityRelationship, String property, Object value) {
		try {
			viewController.update(entityRelationship, property, value);
		} catch(Exception e) {
			exceptionCatched(e);
		}		
	}	
	public void doubleClick(EntityRelationship first) {
		String defaultAction = first.getEntity().getEntityType().getDefaultAction();
		if(GenericValidator.isBlankOrNull(defaultAction)) 
			defaultAction = "edit";
		defaultAction = defaultAction+"Action";
		try {
			Object action = PropertyUtils.getProperty(treeActionMaker, defaultAction);
			if(action!=null&&action instanceof Action)
				((Action)action).run();
		} catch (Exception e) {
			exceptionCatched(e);
		}
	}
	@Override
	public void keyPressed(EntityRelationship first, KeyEvent keyEvent) {
		if(keyEvent.keyCode==SWT.DEL)
			treeActionMaker.getDeleteAction().run();
		else if ((keyEvent.stateMask == SWT.CTRL) && (keyEvent.keyCode=='N'||keyEvent.keyCode=='n'))
			treeActionMaker.getMenuRightClick().setVisible(true);
		else if(keyEvent.keyCode==SWT.F2) {
			TreeColumn treeColumn = getTreeViewer().getSelectedColumn();
			int index = treeColumn==null?0:getTreeViewer().getTree().indexOf(treeColumn);
			getTreeViewer().editElement(first, index);
		}
	}
	@Override
	public boolean ignoreException(Exception e) {
		return false;
	}
}
